#include <arpa/inet.h>
#include <pthread.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

int tcp_fd;

void func(int);
void* rec(void*);

int main(int argc, char const *argv[])
{
    pthread_t tid;
    // 1.创建套接字
    tcp_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (tcp_fd == -1)
    {
        perror("socket error\n");
        return -1;
    }

    // 2.设置套接字选项，允许接收带外数据
    int flag = 1;
    if (setsockopt(tcp_fd, SOL_SOCKET, SO_OOBINLINE, &flag, sizeof(flag)) == -1)
    {
        perror("setsockopt error\n");
        return -1;
    }

    // 3.准备服务端的地址数据
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;    // ipv4
    server_addr.sin_port = htons(50000); // 该端口为服务器端口
    inet_pton(AF_INET, "192.168.11.24", &server_addr.sin_addr);

    // 4.发起连接请求
    printf("发起连接请求\n");
    int ret = connect(tcp_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret == -1)
    {
        perror("连接失败\n");
        return -1;
    }
    printf("连接成功\n");

    // 5.发送数据
    signal(SIGURG, func);
    fcntl(tcp_fd, F_SETOWN, getpid());
    pthread_create(&tid,NULL,rec,(void*)&tcp_fd);
    char buf[1024] = {0};
    while (1)
    {
        memset(buf, 0, 1024);
        printf("请输入准备发送的数据\n");
        scanf("%s", buf);
        write(tcp_fd, buf, strlen(buf));
        if (strcmp(buf, "bye") == 0)
            break;
    }

    // 6.关闭套接字
    close(tcp_fd);

    return 0;
}

void func(int num)
{
    char buf[1024] = {0};
    int ret = recv(tcp_fd, buf, 1024, MSG_OOB);
    if (ret > 0)
    {
        printf("接收到带外数据: %s\n", buf);

        printf("server is exit\n");

        close(tcp_fd);
        exit(0);
    }
}

void* rec(void* data)
{
  char buf[1024];
  while(1)
  {
    recv(*(int*)data,buf,1024,MSG_OOB);
    printf("read is %s\n",buf);
  }

  pthread_exit(NULL);
}
